package Implementacion;

import java.util.ArrayList;
import java.util.List;

import Entidades.Coordenada;
import Entidades.Plano;
import Entidades.Planta;
import Implementaciones.Conjunto;
import Interfaces.RobotDesastresInterface;
import Principal.RobotDesastresMetodos;
import TDA.ColaTDA;
import TDA.ConjuntoTDA;

public class RobotDesastres implements RobotDesastresInterface {

	/**
	 * O(n4)
	 */
	public void RescatarVictimas(Plano plano,
			ConjuntoTDA<Coordenada> coordVictimas,
			ConjuntoTDA<Coordenada> victimasRescatadas,
			ColaTDA<Coordenada> secuenciaPuntosVisitados) throws Exception {

		for (int i = 0; i < plano.ObtenerCantidadPlantas(); i++) { // n
			// dibujo la planta
			System.out.println("Planta " + i);
			dibujarPlano(plano, coordVictimas, i);

			// inicializo el conjunto de victimas rescatadas
			ConjuntoTDA<Coordenada> rescatados = new Conjunto<Coordenada>(); // c
			rescatados.inicializarConjunto(); // c

			// inicializo las demas variables
			Planta planta = plano.ObtenerPlanta(i); // c
			Coordenada coordenadaInicial = new Coordenada(0, 0, i); // c

			// resuelvo la planta
			// n3
			ColaTDA<Coordenada> visitados = RobotDesastresMetodos.analizarPlanta(
					planta, coordenadaInicial, coordVictimas); // xxxx

			// n (todo el bloque)
			if (visitados.colaVacia()) {
				// si no se rescato ninguna victima
				System.out
						.println("No hay victimas o no pueden ser rescatadas.\n\n"); // c
			} else {
				// si se rescataron victimas se muestra el camino recorrido
				System.out.print("Camino: ");
				while (!visitados.colaVacia()) { // n
					Coordenada coordenada = visitados.primero(); // c
					System.out.print(coordenada + "->"); // c
					visitados.desacolar(); // c
					//secuenciaPuntosVisitados.acolar(coordenada);
				}
				System.out.print("[return]\n\n");
			}
		}
	}

	/**
	 * O(n2)
	 * @param plano
	 * @param victimas
	 * @param nroPlanta
	 * @throws Exception
	 */
	private static void dibujarPlano(Plano plano,
			ConjuntoTDA<Coordenada> victimas, int nroPlanta) throws Exception {

		List<Coordenada> listaCoord = new ArrayList<Coordenada>();

		Planta planta = plano.ObtenerPlanta(nroPlanta);
		Planta plantaAux = new Planta(planta.obtenerDimensionPlanta(), 0);

		// preparo mi plano auxiliar de inaccesibilidad
		for (int i = 0; i < planta.obtenerDimensionPlanta(); i++) {
			for (int j = 0; j < planta.obtenerDimensionPlanta(); j++) {
				plantaAux.setearInaccesible(i, j);
			}
		}

		// marco los lugares de las victimas como lugares accesibles en el plano
		// auxiliar
		Coordenada coordenada;
		while (!victimas.conjuntoVacio()) {
			coordenada = victimas.elegir();
			listaCoord.add(coordenada);
			if (coordenada.obtenerNroPlanta() == nroPlanta) {
				plantaAux.setearAccesible(coordenada.obtenerPosicionY(),
						coordenada.obtenerPosicionX());
			}
			victimas.sacar(coordenada);
		}

		// dibujo la matriz
		dibujarMatriz(planta, plantaAux);

		// vuelvo a cargar mi lista de victimas
		for (Coordenada coord : listaCoord) {
			victimas.agregar(coord);
		}
	}

	/** 
	 * O(n2)
	 * @param planta
	 * @param pl
	 */
	private static void dibujarMatriz(Planta p1, Planta p2) { // p1: real - p2:
																// inaccesibles

		for (int i = 0; i < p1.obtenerDimensionPlanta(); i++) {
			System.out.print("|");
			for (int j = 0; j < p1.obtenerDimensionPlanta(); j++) {
				if (p2.esAccesible(i, j)) {
					// Para ver estos simbolos (codificacion UTF-8), ir a
					// Run -> Run Configurations... -> (proyecto) -> Common ->
					// Encoding
					// victimas
					if (Math.random() < 0.5)
						System.out.print(" ♀ ");
					else
						System.out.print(" ♂ ");
				} else if (!p1.esAccesible(i, j)) {
					// lugares inaccesibles
					System.out.print(" x ");
				} else {
					// espacios libres
					System.out.print(" . ");
				}
				System.out.print("|");
			}
			System.out.println();
		}
	}

}
